<?php
/*********************************************
 *  CPG Dragonfly™ CMS
 *********************************************
	Copyright © since 2010 by CPG-Nuke Dev Team
	http://dragonflycms.org

	Dragonfly is released under the terms and conditions
	of the GNU GPL version 2 or any later version
*/

namespace Poodle;

abstract class Auth
{

	const
		ERR_FAILURE            = 1,
		ERR_IDENTITY_NOT_FOUND = 2, # Failure due to identity not being found.
		ERR_IDENTITY_AMBIGUOUS = 3, # Failure due to identity being ambiguous.
		ERR_CREDENTIAL_INVALID = 4, # Failure due to invalid credential being supplied.
		ERR_UNKNOWN            = 5; # Failure due to unknown reasons.

	public static function secureClaimedID($id)
	{
		return \Poodle\Hash::string('sha1', mb_strtolower($id));
	}

	protected static function getAlgo($algo)
	{
		$algos = array(
			$algo,
			\Poodle::getKernel()->CFG->auth->default_pass_hash_algo,
			'bcrypt'
		);
		foreach ($algos as $algo) {
			if ($algo && \Poodle\Hash::available($algo)) {
				return $algo;
			}
		}
		// Not secure but always better then none at all
		return 'sha1';
	}

	public static function generatePassword($length=8, $chars='')
	{
		if ($chars)  { $chars = is_array($chars) ? $chars : str_split($chars); }
		if (!$chars) { $chars = range(33, 126); }
		$pass  = '';
		shuffle($chars);
		$l = count($chars)-1;
		for ($x=0; $x<$length; ++$x) {
			$c = $chars[mt_rand(0, $l)];
			$pass .= is_int($c) ? chr($c) : $c;
		}
		return $pass;
	}

	public static function hashPassword($password, $algo=null)
	{
		if ($password) {
			$algo = self::getAlgo($algo);
			return $algo.':'.\Poodle\Hash::string($algo,$password);
		}
		return null;
	}

	public static function update($identity_id, $provider_id, $claimed_id, $password=null, $algo=null)
	{
		return self::updateHashed($identity_id, $provider_id, $claimed_id, self::hashPassword($password, $algo));
	}

	public static function updateHashed($identity_id, $provider_id, $claimed_id, $password)
	{
		$identity_id = (int)$identity_id;
		$provider_id = (int)$provider_id;
		if (1 > $identity_id || 1 > $provider_id) return false;

		$SQL = \Poodle::getKernel()->SQL;
		$tbl = $SQL->TBL->auth_identities;
		$claimed_id = self::secureClaimedID($claimed_id);
		$where = "auth_provider_id={$provider_id} AND auth_claimed_id=".$SQL->quote($claimed_id);
		if (!$tbl->count($where))
		{
			return $tbl->insert(array(
				'identity_id'      => $identity_id,
				'auth_provider_id' => $provider_id,
				'auth_claimed_id'  => $claimed_id,
				'auth_password'    => $password,
			));
		}
		return $tbl->update(array(
//			'auth_claimed_id' => $claimed_id,
			'auth_password' => $password,
		), "identity_id={$identity_id} AND {$where}");
	}
}
